import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;


public class SFL 
{
	private Collection<Component> components;
	private Collection<Test> tests;
	private CoverageMatrix coverageMatrix;

	public SFL(Collection<Component> C, Collection<Test> T, CoverageMatrix A)
	{
		components = C;
		tests = T;
		coverageMatrix = A;
	}

	/**
	 * Runs the SFL algorithm.
	 * 
	 * @return Component Ranking - 
	 * List of pairs <c, P(c)> sorted by P, where P is the chance that component c is broken.
	 */
	public List<Pair<Component, Double>> Run()
	{
		List<Pair<Component, Double>> ans = new LinkedList<Pair<Component, Double>>();

		int counter = 0;
		for(Component c : components)
		{
			//calc formula of sj
			double n11_j = 0, n10_j = 0, n01_j = 0;
			for(Test i : tests)
			{
				if(coverageMatrix.isComponentCoveredByTest(c, i))
				{
					if(i.getTestFailed()) n11_j++; 
					else n10_j++;
				}
				else if(i.getTestFailed()) n01_j++;
			}
			double sj = n11_j / Math.sqrt((n11_j + n01_j)*(n11_j + n10_j));
			if(sj != sj)
				sj = 0;
			ans.add(new Pair<Component, Double>(c, Double.valueOf(sj)));
			counter ++;
		}
		//now sort in non-ascending order
		Collections.sort(ans, new Comparator<Pair<Component, Double>>() 
				{
			public int compare(Pair<Component, Double> l, Pair<Component, Double> r)
			{
				return Double.compare(l.second, r.second);
			}
				});	
		return ans;
	}

}
